﻿using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Speaker;
using System.Threading.Tasks;
//using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
using english_sentences.Services.Interface;
using System.Text;

namespace english_sentences.Services
{
    public class VoiceService : IVoiceService
    {
        private readonly IConfiguration _configuration;
        private readonly string TokenUri = "https://eastasia.api.cognitive.microsoft.com/sts/v1.0/issuetoken";
        private readonly string SpeechUri = "https://eastasia.tts.speech.microsoft.com/cognitiveservices/v1";
        private readonly string speechKey;



        public VoiceService(IConfiguration configuration)
        {
            this._configuration = configuration;
            this.speechKey = this._configuration.GetSection("SPEECH_KEY").Value;
        }

        public async Task<VoiceResult> SynthesizeAsync(string text, string voiceType)
        {
            var token = await this.getAccessToken();

            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
                client.DefaultRequestHeaders.Add("X-Microsoft-OutputFormat", "audio-48khz-192kbitrate-mono-mp3");
                client.DefaultRequestHeaders.Add("User-Agent", "custom agent");

                UriBuilder uriBuilder = new UriBuilder(this.SpeechUri);

                string xml = $"<speak version='1.0' xml:lang='en-US' xmlns:mstts='https://www.w3.org/2001/mstts'><voice name='{voiceType}'><mstts:express-as style='chat'>{text}</mstts:express-as></voice></speak>";

                var content = new StringContent(xml, Encoding.UTF8, "application/ssml+xml");

                var result = await client.PostAsync(uriBuilder.Uri.AbsoluteUri, content);
                var fileSize = result.Content.Headers.ContentLength;
                var bitRate = 192 * 1000;
                var duration = ((fileSize / (bitRate / 8)) * 1000) + ((fileSize % (bitRate / 8) * 1000) / bitRate);

                byte[] bytes = await result.Content.ReadAsByteArrayAsync();

                if (bytes == null || bytes.Length == 0)
                {
                    throw new Exception("failed to synthesize voices.");
                }
                return new VoiceResult { Bytes = bytes, Duration = duration ?? 0 };

            }




        }

        private async Task<string> getAccessToken()
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", this.speechKey);

                UriBuilder uriBuilder = new UriBuilder(this.TokenUri);

                var result = await client.PostAsync(uriBuilder.Uri.AbsoluteUri, null);

                return await result.Content.ReadAsStringAsync();
            }
        }


    }
}
